package decorator;

/**
 * Created by 0171093 on 2018/2/2.
 * 装饰模式（decorator） 表示动态的给一个对象添加一些新的功能
 * 装饰模式（Decorator）也叫包装器模式（Wrapper）
 * Component：定义一个对象接口，可以给这些对象动态添加职责。
 * 真实对象和装饰者对象有相同的接口，这样客户端不用知道内部有装饰者对象存在的，还是以之前处理真实对象的相同方式来和装饰者对象交互
 * ConcreteComponent：是定义了一个具体的对象（例如：人），也可以给这个对象添加一些其他职责
 * Decorator：装饰抽象类，继承了Component，从外类来扩展Component类的功能
 * ConcreteDecorator：就是具体的装饰对象了（衣服，鞋子..），它起到了给Component添加职责的功能。
 * <p/>
 * 装饰模式降低系统的耦合度，可以动态的增加或删除对象的职责，并使得需要装饰的具体构建类和具体装饰类可以独立变化
 * 以便增加新的具体构建类和具体装饰类。
 * <p/>
 * 优点
 * 扩展功能强，相比继承来说更灵活。继承的话会导致子类个数增加。而装饰者模式不会出现这种情况
 * 可以对一个对象进行多次装饰，创造出不同行为的组合，得到功能更加强大的对象。
 * 具体构建类和具体装饰类可以独立变化，用户可以根据需要自己增加新的构件子类和具体装饰类。
 * <p/>
 * 缺点
 * 产生很多小对象，大量小对象会占据内存。一定程度上影响了性能。
 * 装饰模式易于出错，调试排查比较麻烦。
 * <p/>
 * <p/>
 * 开发中应用的场景
 * <p/>
 * IO中输入流和输出流
 * Struts2中，request，response，session对象的处理。
 */
public class main {


    public static void main(String[] args) {

        Car car = new Car();
        car.move();//这里打印未增加新功能的时候：汽车移动

        System.out.println("--------增加飞行功能-------");
        FlayCar flyCar = new FlayCar(car);//将真实对象传入装饰对象中
        flyCar.move();//这里就是增加了飞行后的装饰

        System.out.println("--------增加潜水功能-------");
        WaterCar waterCar = new WaterCar(car);//将真实对象传入装饰对象中
        waterCar.move();//这里就是增加了潜水功能后的装饰
    }

}
